/*
 * @(#)Test.java V2.0 2015年5月9日
 * 百联集团	版权所有
 *
 * 对象浅拷贝工具类
 *
 * @Title: ReflectionUtil.java
 * @Package com.iokbl.www.cart.util
 * @author 李瑞敏
 * @date 2015年5月9日 下午1:11:23
 * @version V2.0
 * 历史版本：
 * 	1. 【2015年5月9日】 创建文件   by 李瑞敏
 */
package com.tenebrous.jestic.utils;

import org.springframework.beans.*;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 对象浅拷贝工具类
 */
public class ReflectionUtils {

    /**
     * 获取对象属性
     *
     * @param source
     * @param property
     * @return
     */
    public static Object getProperty(Object source, String property) {
        BeanWrapper sourceBw = new BeanWrapperImpl(source);
        return sourceBw.getPropertyValue(property);
    }

    /**
     * 设置对象的属性信息
     *
     * @param source
     * @param property
     * @param value
     */
    public static void setProperty(Object source, String property, Object value) {
        BeanWrapper sourceBw = new BeanWrapperImpl(source);
        sourceBw.setPropertyValue(property, value);
    }

    /**
     * 拷贝属性信息,合部拷贝
     *
     * @param src
     * @param target
     */
    public static void copyProperties(Object src, Object target) {
        copyProperties(src, target, null);
    }

    /**
     * 拷贝属性信息,只拷贝不为空的对象
     *
     * @param source
     * @param target
     */
    public static void copyNotEmptyProperties(Object source, Object target) {
        if ((source == null) || (target == null)) {
            throw new IllegalArgumentException(
                    "Source and target must not be null");
        }

        BeanWrapper sourceBw = new BeanWrapperImpl(source);
        BeanWrapper targetBw = new BeanWrapperImpl(target);
        MutablePropertyValues values = new MutablePropertyValues();
        for (int i = 0; i < sourceBw.getPropertyDescriptors().length; i++) {
            PropertyDescriptor sourceDesc = sourceBw.getPropertyDescriptors()[i];
            String name = sourceDesc.getName();
            try {
                PropertyDescriptor targetDesc = targetBw
                        .getPropertyDescriptor(name);
                if ((targetDesc.getWriteMethod() == null)
                        || (sourceDesc.getReadMethod() == null))
                    continue;
                Object value = sourceBw.getPropertyValue(name);
                if ((value != null) && (value.toString().trim().length() > 0))
                    values.addPropertyValue(new PropertyValue(name, value));
            } catch (BeansException localBeansException) {
                localBeansException.printStackTrace();
            }
        }
        targetBw.setPropertyValues(values);
    }

    /**
     * 自定义拷贝对象
     *
     * @param source
     * @param target
     * @param ignoreProperties
     */
    public static void copyProperties(Object source, Object target,
                                      String[] ignoreProperties) {
        if ((source == null) || (target == null)) {
            throw new IllegalArgumentException(
                    "Source and target must not be null");
        }
        List<String> ignoreList = ignoreProperties != null ? Arrays
                .asList(ignoreProperties) : new ArrayList<String>();
        BeanWrapper sourceBw = new BeanWrapperImpl(source);
        BeanWrapper targetBw = new BeanWrapperImpl(target);
        MutablePropertyValues values = new MutablePropertyValues();

        //排除两个对象的不同字段
        for (int p = 0; p < sourceBw.getPropertyDescriptors().length; p++) {
            String feildName1 = sourceBw.getPropertyDescriptors()[p].getName();
            Boolean flag = false;//标记目标类是否包含该属性
            for (int q = 0; q < targetBw.getPropertyDescriptors().length; q++) {
                String feildName2 = targetBw.getPropertyDescriptors()[q].getName();
                if (feildName1.equals(feildName2)) {
                    flag = true;
                    break;
                }
            }
            if (!flag) {
                ignoreList.add(feildName1);
            }
        }
        for (int i = 0; i < sourceBw.getPropertyDescriptors().length; i++) {
            PropertyDescriptor sourceDesc = sourceBw.getPropertyDescriptors()[i];
            String name = sourceDesc.getName();
            try {
                if (ignoreList.contains(name)) {
                    continue;//不拷贝排除列表中的字段
                }
                PropertyDescriptor targetDesc = targetBw
                        .getPropertyDescriptor(name);
                if ((targetDesc.getWriteMethod() == null)
                        || (sourceDesc.getReadMethod() == null)
                        || ((ignoreProperties != null) && (ignoreList
                        .contains(name))))
                    continue;
                values.addPropertyValue(new PropertyValue(name, sourceBw
                        .getPropertyValue(name)));
            } catch (BeansException localBeansException) {
                localBeansException.printStackTrace();
            }
        }
        targetBw.setPropertyValues(values);
    }


    public static void trim(Object obj) {
        try {
            Field[] fs = obj.getClass().getDeclaredFields();
            for (int i = 0; i < fs.length; i++) {
                Field f = fs[i];
                f.setAccessible(true); //设置属性是可以访问的
                Object val = f.get(obj);//得到此属性的值
                String type = f.getType().toString();//得到此属性的类型
                if (type.endsWith("String")) {
                    if (null == val || "".equals(val.toString()) || "NULL".equals(val.toString().toUpperCase()) || "undefined".equals(val.toString().toUpperCase())) {
                        f.set(obj, null); //将空字符串或设置为空对象
                    } else {
                        f.set(obj, val.toString().trim()); //去除空格
                    }
                }
            }
        } catch (IllegalAccessException e) {
        }
    }

}